﻿using System;
using Microsoft.SharePoint;
using SharePoint.Orm.Helpers;

namespace SharePoint.Orm.TestHelpers {
	public static class SiteHelpers {
		public const string Url = "http://localhost/SPOrm";
		public const string ContentType1Name = "ContentType1";
		public const string ContentType2Name = "ContentType2";
		public const string List1Name = "List1";
		public const string List2Name = "List2";
		public const string List3Name = "List3";
		public const string List4Name = "List4";
		public const string List5Name = "List5";
		public const string List6Name = "List6";
		public const string Field1Name = "Field1";
		public const string Field2Name = "Field2";
		public const string Field3Name = "Field3 Name With Space";
		public const string Field4SiteFieldName = "Field4SiteField";
		public const string Field4SiteStaticName = "Field4SiteStaticName";
		public const string Field4SiteTitle = "Field4SiteTitle";
		public const string Field4LinkDisplayName = "Field4LinkDisplayName";
		public const string Field5Name = "Field5";
		public const string List2Field1Name = "List2Field1";
		public const string List3Field1Name = "List3Field1";
		public const string List4FieldText = "List4FieldText";
		public const string List4FieldDateTime = "List4FieldDateTime";
		public const string List4FieldNote = "List4FieldNote";
		public const string List4FieldInteger = "List4FieldInteger";
		public const string List4FieldGuid = "List4FieldGuid";
		public const string List4FieldBoolean = "List4FieldBoolean";
		public const string List4FieldLookup = "List4FieldLookup";
		public const string List4FieldChoice = "List4FieldChoice";
		public const string List4FieldFile = "List4FieldFile";
		public const string List4FieldComputed = "List4FieldComputed";
		public const string List4FieldUser = "List4FieldUser";
		public const string List4FieldInvalid = "List4FieldInvalid";
		public const string List4FieldWorkflowStatus = "List4FieldWorkflowStatus";
		public const string List4FieldURL = "List4FieldURL";
		public const string List4FieldAllDayEvent = "List4FieldAllDayEvent";
		public const string List4FieldRecurrence = "List4FieldRecurrence";
		public const string List4FieldCrossProjectLink = "List4FieldCrossProjectLink";
		public const string List4FieldNumber = "List4FieldNumber";
		public const string List4FieldWorkflowEventType = "List4FieldWorkflowEventType";
		private static bool _ensureSiteCalled;
		private static Guid _field4Id;
		public static SPField _field1;
		public static SPField _field2;
		public static SPField _field3;
		public static SPFieldLookup _field5;

		public static void EnsureSite() {
			if (_ensureSiteCalled) {
				return;
			}
			using (SPSite web = new SPSite(Url))
			using (SPWeb site = web.OpenWeb()) {
				if (site.Title != "SPOrm") {
					throw new Exception("Could not find 'SPOrm' site. You must create a site at '" + Url + "' with name 'SPOrm'.");
				}
				EnsureContentType1(site);
				EnsureList1(site);
				EnsureList2(site);
				EnsureList3(site);
				EnsureList4(site);
				EnsureList5(site);

				EnsureContentType2(site);
				EnsureList6(site);
			}
			_ensureSiteCalled = true;
		}

		private static SPContentType EnsureContentType1(SPWeb site) {
			EnsureFields(site);

			SPContentType contentType1 = SPWebHelper.FindOrAddContentType(site, "sporm", ContentType1Name, SPBuiltInContentTypeId.Item);
			SPContentTypeHelper.FindOrAddFieldLink(contentType1, Field1Name, site.Fields[Field1Name]);
			SPContentTypeHelper.FindOrAddFieldLink(contentType1, Field2Name, site.Fields[Field2Name]);
			SPContentTypeHelper.FindOrAddFieldLink(contentType1, Field3Name, site.Fields[Field3Name]);
			SPFieldLink link = SPContentTypeHelper.FindOrAddFieldLink(contentType1, Field4SiteFieldName, site.Fields[_field4Id]);
			link.DisplayName = Field4LinkDisplayName;
			contentType1.Update(true);

			return contentType1;
		}

		private static SPContentType EnsureContentType2(SPWeb site) {
			SPContentType contentType2 = SPWebHelper.FindOrAddContentType(site, "sporm", ContentType2Name, SPBuiltInContentTypeId.Contact);
			contentType2.Update(true);

			return contentType2;
		}

		private static void EnsureFields(SPWeb site) {
			_field1 = SPWebHelper.FindOrAddField(site, new Guid("4B2ECB3A-8648-4256-A31B-7BFA8925598B"), "sporm", Field1Name, SPFieldType.Text, false);
			_field2 = SPWebHelper.FindOrAddField(site, new Guid("B080FF62-04D6-4D64-8E84-F8AD736891BB"), "sporm", Field2Name, SPFieldType.Number, false);
			_field3 = SPWebHelper.FindOrAddField(site, new Guid("0342A5C0-7F7E-4495-90B5-677F1C941C6F"), "sporm", Field3Name, SPFieldType.Number, false);
			SPField field = SPWebHelper.FindOrAddField(site, new Guid("F2C57F23-B197-42D6-A465-D0D2F78C013A"), "sporm", Field4SiteFieldName, SPFieldType.Text, false);
			field.StaticName = Field4SiteStaticName;
			field.Title = Field4SiteTitle;
			field.Update(true);
			_field4Id = field.Id;
		}

		public static SPList EnsureList1(SPWeb site) {
			SPContentType contentType1 = EnsureContentType1(site);
			SPList list = SPWebHelper.FindOrAddList(site, List1Name, "SPOrm Test List1", SPListTemplateType.GenericList);
			SPListHelper.SetContentType(list, contentType1);

			_field5 = SPWebHelper.FindOrAddFieldLookup(site, new Guid("850A3501-6B1B-41D5-8CB1-2169D2BFC773"), "sporm", Field5Name, list.ID, false);

			return list;
		}

		public static SPList EnsureList2(SPWeb site) {
			SPList list = SPWebHelper.FindOrAddList(site, List2Name, "SPOrm Test List2", SPListTemplateType.GenericList);
			SPListHelper.FindOrAddField(list, List2Field1Name, SPFieldType.Text, false);
			return list;
		}

		private static SPList EnsureList3(SPWeb site) {
			SPList list = SPWebHelper.FindOrAddList(site, List3Name, "SPOrm Test List3", SPListTemplateType.GenericList);
			SPListHelper.FindOrAddField(list, List3Field1Name, SPFieldType.Text, false);
			return list;
		}

		private static SPList EnsureList4(SPWeb site) {
			SPList list = SPWebHelper.FindOrAddList(site, List4Name, "List4", SPListTemplateType.GenericList);
			SPListHelper.FindOrAddField(list, List4FieldText, SPFieldType.Text, false);
			SPListHelper.FindOrAddField(list, List4FieldDateTime, SPFieldType.DateTime, false);
			SPListHelper.FindOrAddField(list, List4FieldNote, SPFieldType.Note, false);
			SPListHelper.FindOrAddField(list, List4FieldInteger, SPFieldType.Integer, false);
			SPListHelper.FindOrAddField(list, List4FieldGuid, SPFieldType.Guid, false);
			SPListHelper.FindOrAddField(list, List4FieldBoolean, SPFieldType.Boolean, false);
			SPListHelper.FindOrAddField(list, List4FieldChoice, SPFieldType.Choice, false);
			SPListHelper.FindOrAddField(list, List4FieldUser, SPFieldType.User, false);
			SPListHelper.FindOrAddField(list, List4FieldURL, SPFieldType.URL, false);
			SPListHelper.FindOrAddField(list, List4FieldNumber, SPFieldType.Number, false);
			SPListHelper.FindOrAddField(list, List4FieldWorkflowEventType, SPFieldType.WorkflowEventType, false);

			SPField field = list.FindFieldOrDefault(List4FieldLookup);
			if (field == null) {
				list.Fields.AddLookup(List4FieldLookup, EnsureList1(site).ID, false);
			}
			//SPListHelper.FindOrAddField(list, List4FieldFile, SPFieldType.File, false);
			//SPListHelper.FindOrAddField(list, List4FieldComputed, SPFieldType.Computed, false);
			//SPListHelper.FindOrAddField(list, List4FieldInvalid, SPFieldType.Invalid, false);
			//SPListHelper.FindOrAddField(list, List4FieldWorkflowStatus, SPFieldType.WorkflowStatus, false);
			//SPListHelper.FindOrAddField(list, List4FieldAllDayEvent, SPFieldType.AllDayEvent, false);
			//SPListHelper.FindOrAddField(list, List4FieldRecurrence, SPFieldType.Recurrence, false);
			//SPListHelper.FindOrAddField(list, List4FieldCrossProjectLink, SPFieldType.CrossProjectLink, false);

			return list;
		}

		private static SPList EnsureList5(SPWeb site) {
			SPList list = SPWebHelper.FindOrAddList(site, List5Name, "SPOrm Test List5", SPListTemplateType.DocumentLibrary);
			return list;
		}

		public static SPList EnsureList6(SPWeb site) {
			SPContentType contentType2 = EnsureContentType2(site);
			SPList list = SPWebHelper.FindOrAddList(site, List6Name, "SPOrm Test List6", SPListTemplateType.Contacts);
			SPListHelper.SetContentType(list, contentType2);
			return list;
		}

		public static void RemoveData() {
			EnsureSite();
			using (SPSite web = new SPSite(Url))
			using (SPWeb site = web.OpenWeb()) {
				SPList list1 = EnsureList1(site);
				while (list1.Items.Count > 0) {
					list1.Items.Delete(0);
				}

				SPList list2 = EnsureList2(site);
				while (list2.Items.Count > 0) {
					list2.Items.Delete(0);
				}

				SPList list3 = EnsureList3(site);
				while (list3.Items.Count > 0) {
					list3.Items.Delete(0);
				}

				SPList list4 = EnsureList4(site);
				while (list4.Items.Count > 0) {
					list4.Items.Delete(0);
				}

				SPList list5 = EnsureList5(site);
				while (list5.Items.Count > 0) {
					list5.Items.Delete(0);
				}
			}
		}
	}
}
